home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows 95 API Bible
/
Windows 95 API Bible 3 Disc Set.iso
/
Win32 API Bible Book 3 of 3
/
CHAPTE21
/
FRAME.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-29
|
16KB
|
589 lines
#include <windows.h>
#include <stdio.h>
#include "Frame.h"
#include <vfw.h>
#if defined (WIN32)
#define IS_WIN32 TRUE
#else
#define IS_WIN32 FALSE
#endif
#define IS_NT IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
#define IS_WIN32S IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
#define IS_WIN95 (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
HINSTANCE hInst; // current instance
LPCTSTR lpszAppName = "MyApp";
LPCTSTR lpszTitle = "My Application";
// the rest of the stuff
//......................
BOOL RegisterWin95( CONST WNDCLASS* lpwc );
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, lpszAppName);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = lpszAppName;
wc.lpszClassName = lpszAppName;
if ( IS_WIN95 )
{
if ( !RegisterWin95( &wc ) )
return( FALSE );
}
else if ( !RegisterClass( &wc ) )
return( FALSE );
hInst = hInstance;
hWnd = CreateWindow( lpszAppName,
lpszTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hInstance,
NULL
);
if ( !hWnd )
return( FALSE );
ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );
while( GetMessage( &msg, NULL, 0, 0) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
}
BOOL RegisterWin95( CONST WNDCLASS* lpwc )
{
WNDCLASSEX wcex;
wcex.style = lpwc->style;
wcex.lpfnWndProc = lpwc->lpfnWndProc;
wcex.cbClsExtra = lpwc->cbClsExtra;
wcex.cbWndExtra = lpwc->cbWndExtra;
wcex.hInstance = lpwc->hInstance;
wcex.hIcon = lpwc->hIcon;
wcex.hCursor = lpwc->hCursor;
wcex.hbrBackground = lpwc->hbrBackground;
wcex.lpszMenuName = lpwc->lpszMenuName;
wcex.lpszClassName = lpwc->lpszClassName;
// Added elements for Windows 95.
//...............................
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hIconSm = LoadImage(wcex.hInstance, lpwc->lpszClassName,
IMAGE_ICON, 16, 16,
LR_DEFAULTCOLOR );
return RegisterClassEx( &wcex );
}
LRESULT CALLBACK About( HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if ( LOWORD(wParam) == IDOK
|| LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
#define MSG_LEN 1024
char msg[MSG_LEN+1];
int nTabStop = 120;
HWND hListBox = NULL;
int nFrameHeight = 50;
VOID OpenAvi(HWND hWnd);
VOID CloseAvi();
VOID Prev(HWND hWnd);
VOID Next(HWND hWnd);
VOID DrawFrame(HWND hWnd); // calls PaintFrame()
VOID PaintFrame(HWND hWnd, HDC hDC); // called by DrawFrame and WM_PAINT
VOID DisplayStats(HWND hWnd);
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_CREATE :
// initialize the AVI library DLL
//...............................
AVIFileInit();
// Create ListBox
//...............
hListBox = CreateWindow( "LISTBOX", "",
WS_CHILD | LBS_NOTIFY |
WS_VSCROLL | WS_BORDER |
WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
LBS_USETABSTOPS,
0, 0,
0, 0,
hWnd,
(HMENU)101,
hInst,
NULL );
SendMessage(hListBox, LB_SETTABSTOPS, 1, (LPARAM)&nTabStop);
OpenAvi(hWnd);
break;
case WM_SIZE :
MoveWindow(hListBox, 0, nFrameHeight+1,
LOWORD(lParam),
HIWORD(lParam)-nFrameHeight-1, TRUE);
break;
case WM_COMMAND :
switch( LOWORD(wParam) )
{
case IDM_PREV:
Prev(hWnd);
break;
case IDM_NEXT:
Next(hWnd);
break;
case IDM_ABOUT :
DialogBox( hInst, "AboutBox", hWnd, About );
break;
case IDM_EXIT :
DestroyWindow( hWnd );
break;
}
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
if (hDC)
PaintFrame(hWnd, hDC);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY :
// release the AVI library DLL
//............................
CloseAvi();
AVIFileExit();
PostQuitMessage(0);
break;
default :
return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
}
return(0L);
}
/*****************************************************************************
* Global variables
*
*
*
******************************************************************************/
HRESULT rc;
LPCTSTR lpszInputFilename = "Large.avi";
PAVIFILE pAviIn = NULL;
PAVISTREAM pAudioStream = NULL;
PAVISTREAM pVideoStream = NULL;
PGETFRAME pVideoFrame = NULL;
HDRAWDIB hDrawDibDC = NULL;
LONG nFrame;
/*****************************************************************************
* OpenAvi
*
*
*
******************************************************************************/
VOID OpenAvi(HWND hWnd)
{
LONG i;
AVIFILEINFO pFileInfo;
PAVISTREAM pAviStream;
AVISTREAMINFO StreamInfo;
// open input AVI file
//....................
rc = AVIFileOpen(&pAviIn, lpszInputFilename, OF_READ, NULL);
if (rc) // if error
{
MessageBox(hWnd, "Error opening AVI file.",
NULL, MB_OK);
return;
}
// get input AVI file info
//........................
pFileInfo.dwStreams = 0L;
rc = AVIFileInfo(pAviIn, &pFileInfo, sizeof(AVIFILEINFO));
// find video stream
//.................
for (i = 0; i < (LONG)pFileInfo.dwStreams; i++)
{
rc = AVIFileGetStream(pAviIn, &pAviStream, 0L, i);
if (rc)
break;
rc = AVIStreamInfo(pAviStream, &StreamInfo, sizeof(AVISTREAMINFO));
if (rc)
continue;
if (StreamInfo.fccType == streamtypeVIDEO)
{
pVideoStream = pAviStream;
AVIStreamAddRef(pVideoStream);
nFrameHeight = StreamInfo.rcFrame.bottom - StreamInfo.rcFrame.top;
}
else if (StreamInfo.fccType == streamtypeAUDIO)
{
pAudioStream = pAviStream;
AVIStreamAddRef(pAudioStream);
}
}
// draw first frame
//.................
if (pVideoStream)
{
pVideoFrame = AVIStreamGetFrameOpen(pVideoStream,
(LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);
hDrawDibDC = DrawDibOpen();
// jump into middle of stream at a key frame position
nFrame = AVIStreamFindSample(pVideoStream,
AVIStreamLength(pVideoStream) / 2 +
AVIStreamStart(pVideoStream),
FIND_NEXT | FIND_KEY);
DrawFrame(hWnd);
DisplayStats(hWnd);
}
else
MessageBox(hWnd, "Video stream not found!", NULL, MB_OK);
}
/*****************************************************************************
* CloseAvi
*
*
*
******************************************************************************/
VOID CloseAvi()
{
// release resources allocated during video decompression
//.......................................................
if (pVideoFrame)
{
AVIStreamGetFrameClose(pVideoFrame);
pVideoFrame = NULL;
}
// release DrawDib stuff
//......................
DrawDibClose(hDrawDibDC);
// release AVI streams
//....................
if (pVideoStream)
AVIStreamRelease(pVideoStream);
if (pAudioStream)
AVIStreamRelease(pAudioStream);
// close AVI file
//...............
AVIFileRelease(pAviIn);
}
/*****************************************************************************
* Prev
*
*
*
******************************************************************************/
VOID Prev(HWND hWnd)
{
if (nFrame > AVIStreamStart(pVideoStream))
{
nFrame--;
DisplayStats(hWnd);
DrawFrame(hWnd);
}
}
/*****************************************************************************
* Next
*
*
*
******************************************************************************/
VOID Next(HWND hWnd)
{
if (nFrame < AVIStreamEnd(pVideoStream))
{
nFrame++;
DisplayStats(hWnd);
DrawFrame(hWnd);
}
}
/*****************************************************************************
* DrawFrame
*
*
*
******************************************************************************/
VOID DrawFrame(HWND hWnd)
{
HDC hDC;
hDC = GetDC(hWnd);
PaintFrame(hWnd, hDC);
ReleaseDC(hWnd, hDC);
}
/*****************************************************************************
* PaintFrame
*
*
*
******************************************************************************/
VOID PaintFrame(HWND hWnd, HDC hDC)
{
AVISTREAMINFO StreamInfo;
LPBITMAPINFOHEADER lpBitmapInfoHeader = NULL;
// Draw video frame DIB
//.....................
AVIStreamInfo(pVideoStream, &StreamInfo, sizeof(AVISTREAMINFO));
lpBitmapInfoHeader = AVIStreamGetFrame(pVideoFrame, nFrame);
DrawDibDraw(hDrawDibDC, hDC,
StreamInfo.rcFrame.left,
StreamInfo.rcFrame.top,
StreamInfo.rcFrame.right - StreamInfo.rcFrame.left,
StreamInfo.rcFrame.bottom - StreamInfo.rcFrame.top,
lpBitmapInfoHeader, NULL,
0, 0, -1, -1,
0);
}
/*****************************************************************************
* DisplayStats
*
* Note: the term "Frame" refers to a video sample
*
******************************************************************************/
#define Display(msg) SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg)
VOID DisplayStats(HWND hWnd)
{
LONG nTime = AVIStreamSampleToTime(pVideoStream, nFrame);
SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
// current frame/time
//......................
sprintf(msg, "Position:\t Frame: %ld Seconds: %ld.%03ld Key frame: %s",
nFrame,
nTime / 1000,
nTime % 1000,
(AVIStreamIsKeyFrame(pVideoStream, nFrame) ? "Yes" : "No"));
Display(msg);
if (pAudioStream)
{
LONG nBeg = AVIStreamSampleToSample(pAudioStream, pVideoStream, nFrame);
LONG nEnd = AVIStreamSampleToSample(pAudioStream, pVideoStream, nFrame+1);
sprintf(msg, "Corresponding audio samples:\t %ld through %ld",
nBeg, nEnd-1);
Display(msg);
}
// prev key frame (frame/time)
//............................
Display("");
sprintf(msg, "Previous key frame:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamPrevKeyFrame(pVideoStream, nFrame),
AVIStreamPrevKeyFrameTime(pVideoStream, nTime) / 1000,
AVIStreamPrevKeyFrameTime(pVideoStream, nTime) % 1000);
Display(msg);
// nearest key frame (frame/time)
//...............................
sprintf(msg, "Nearest key frame:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamNearestKeyFrame(pVideoStream, nFrame),
AVIStreamNearestKeyFrameTime(pVideoStream, nTime) / 1000,
AVIStreamNearestKeyFrameTime(pVideoStream, nTime) % 1000);
Display(msg);
// next key frame (frame/time)
//............................
sprintf(msg, "Next key frame:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamNextKeyFrame(pVideoStream, nFrame),
AVIStreamNextKeyFrameTime(pVideoStream, nTime) / 1000,
AVIStreamNextKeyFrameTime(pVideoStream, nTime) % 1000);
Display(msg);
// prev sample (frame/time)
//.........................
Display("");
sprintf(msg, "Previous sample:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamPrevSample(pVideoStream, nFrame),
AVIStreamPrevSampleTime(pVideoStream, nTime) / 1000,
AVIStreamPrevSampleTime(pVideoStream, nTime) % 1000);
Display(msg);
// nearest sample (frame/time)
//............................
sprintf(msg, "Nearest sample:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamNearestSample(pVideoStream, nFrame),
AVIStreamNearestSampleTime(pVideoStream, nTime) / 1000,
AVIStreamNearestSampleTime(pVideoStream, nTime) % 1000);
Display(msg);
// next sample (frame/time)
//.........................
sprintf(msg, "Next sample:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamNextSample(pVideoStream, nFrame),
AVIStreamNextSampleTime(pVideoStream, nTime) / 1000,
AVIStreamNextSampleTime(pVideoStream, nTime) % 1000);
Display(msg);
// begin frame/time
//.................
Display(""); // blank line
sprintf(msg, "Begin Time:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamStart(pVideoStream),
AVIStreamStartTime(pVideoStream) / 1000,
AVIStreamStartTime(pVideoStream) % 1000);
Display(msg);
// end frame/time
//...............
sprintf(msg, "End Time:\t Frame: %ld Seconds: %ld.%03ld",
AVIStreamEnd(pVideoStream),
AVIStreamEndTime(pVideoStream) / 1000,
AVIStreamEndTime(pVideoStream) % 1000);
Display(msg);
// stream length frames/time
//..........................
sprintf(msg, "Length:\t Frames: %ld Seconds: %ld.%03ld",
AVIStreamLength(pVideoStream),
AVIStreamLengthTime(pVideoStream) / 1000,
AVIStreamLengthTime(pVideoStream) % 1000);
Display(msg);
}